// 
//  DotNetNuke? - http://www.dotnetnuke.com
//  Copyright (c) 2002-2006
//  by DotNetNuke Corporation
// 
//  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
//  documentation files (the "Software"), to deal in the Software without restriction, including without limitation 
//  the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and 
//  to permit persons to whom the Software is furnished to do so, subject to the following conditions:
// 
//  The above copyright notice and this permission notice shall be included in all copies or substantial portions 
//  of the Software.
// 
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 
//  TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
//  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 
//  CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
//  DEALINGS IN THE SOFTWARE.
// 
using System.Web.Services.Protocols;
using System.Diagnostics;
using System.Reflection;
using DotNetNuke.Services.Personalization;
using DotNetNuke.Entities.Users;
using System.Web;
using System;
using DotNetNuke.Modules.IWebCSharp;
using DotNetNuke.Services.Exceptions;
using DotNetNuke.Security.Membership;

namespace DotNetNuke.Modules.IWebCSharp
{
    //  class that is passed in through the soap header
    public class IWebAuthendicationHeader : SoapHeader
    {

        public int PortalID;
        public int UserID;
        public string Username;
        public string Password;
        public string Encrypted;
        public string WebPageCall;
        public int ModuleId;
    }


    public class IWebAuthendication
    {
        //  const values
        private class Consts
        {
            public const string LoginErrorMessage = "Login failed. Invalid credentials supplied to the web service method.";
        }


        private string _MethodName;
        private int _PortalID;
        private int _UserID;
        private string _Username;
        private string _Password;
        private bool _Encrypted;
        private bool _WebPageCall;
        private int _ModuleId;

        #region '"Constructors"'
        public IWebAuthendication(int PortalId, string Username, string Password, bool Encrypted)
        {

            StackTrace st = new StackTrace();
            StackFrame sf = st.GetFrame(1);
            MethodBase mb = sf.GetMethod();

            _MethodName = mb.Name;
            _PortalID = PortalId;
            _Username = Username;
            _Encrypted = Encrypted;
            _Password = GetPassword(Password);
            // set defaults var values not passed to method
            _UserID = 0;
            _WebPageCall = false;
            _ModuleId = 0;

        }
        public IWebAuthendication(int PortalId, string Username, string UserID, string Password, bool Encrypted, bool WebPageCall, string ModuleId)
        {

            StackTrace st = new StackTrace();
            StackFrame sf = st.GetFrame(1);
            MethodBase mb = sf.GetMethod();

            _MethodName = mb.Name;
            _PortalID = PortalId;
            _UserID = Convert.ToInt32(UserID);
            _Username = Username;
            _Encrypted = Encrypted;
            _WebPageCall = Convert.ToBoolean(WebPageCall);
            _ModuleId = Convert.ToInt32(ModuleId);
            _Password = GetPassword(Password);

        }
        public IWebAuthendication(IWebAuthendicationHeader IWebCredentials)
        {
            StackTrace st = new StackTrace();
            StackFrame sf = st.GetFrame(1);
            MethodBase mb = sf.GetMethod();

            if (IWebCredentials.WebPageCall == null)
            {
                IWebCredentials.WebPageCall = "false";
                IWebCredentials.ModuleId = 0;
                IWebCredentials.UserID = 0;
            }

            _MethodName = mb.Name;
            _PortalID = IWebCredentials.PortalID;
            _Username = IWebCredentials.Username;
            _UserID = Convert.ToInt32(IWebCredentials.UserID);
            _Encrypted = Convert.ToBoolean(IWebCredentials.Encrypted);
            _WebPageCall = Convert.ToBoolean(IWebCredentials.WebPageCall);
            _ModuleId = IWebCredentials.ModuleId;
            _Password = GetPassword(IWebCredentials.Password);
        }
        #endregion

        public bool ValidAndAuthorized()
        {
            if (_Password == null || _Username == null)
            {
                throw new SecurityException(Consts.LoginErrorMessage);
            }

            if (IsUserValid())
            {
                UserInfo objUser = new UserInfo();
                objUser = GetUserInfo();
                string strAuthorizedRole = AuthorizedRole();
                return IsAuthorized(objUser, strAuthorizedRole);
            }
            else
            {
                return false;
            }
        }


        private bool IsUserValid()
        {
            UserLoginStatus loginStatus = new UserLoginStatus();

            //  If this is a web page call then decode the password using the key
            //  stored in personalization
            if (_WebPageCall)
            {
                IWebEncryption objIWebEncryption = new IWebEncryption();
                string strEncryptionKey = "";

                //  Get the Encryption Key from Personalization
                PersonalizationController PersonalizationController = new PersonalizationController();
                PersonalizationInfo PersonalizationInfo = new PersonalizationInfo();
                PersonalizationInfo = PersonalizationController.LoadProfile(_UserID, _PortalID);

                if (!(Personalization.GetProfile(PersonalizationInfo, _ModuleId.ToString(), "EncryptionKey") == null))
                {
                    if (((DateTime)(Personalization.GetProfile(PersonalizationInfo, _ModuleId.ToString(), "EncryptionKey_Expires"))) < DateTime.Now)
                    {
                        // Expired Encryption Key
                        return false;
                    }
                    strEncryptionKey = ((string)(Personalization.GetProfile(PersonalizationInfo, _ModuleId.ToString(), "EncryptionKey")));

                    if (_Password == strEncryptionKey)
                    {
                        UserInfo AjaxUser = new UserInfo();
                        AjaxUser = UserController.GetUser(_PortalID, _UserID, false);
                        _Password = UserController.GetPassword(ref AjaxUser, "").ToString();
                    }
                    else
                    {
                        return false;
                    }

                    // Ensure that the _Encrypted flag is set to false
                    _Encrypted = false;
                }
                else
                {
                    // Invalid Encryption Key
                    return false;
                }
            }

            //  If The password is encrypted un-encrypt it first
            if (_Encrypted)
            {
                //  Get the Encryption Key
                string strEncryptionKey = EncryptionKey();
                //  Un-encrypt the password
                IWebEncryption objIWebEncryption = new IWebEncryption();
                _Password = objIWebEncryption.DeCrypt(_Password, strEncryptionKey);
            }

            UserInfo objUser = UserController.ValidateUser(_PortalID, _Username, _Password, "", "", "255.255.255.1", ref loginStatus);
            if (objUser == null)
            {
                return false;
            }
            else
            {
                return true;
            }
        }


        private UserInfo GetUserInfo()
        {
            UserLoginStatus loginStatus = new UserLoginStatus();
            return UserController.ValidateUser(_PortalID, _Username, _Password, "", "", "255.255.255.1", ref loginStatus);
        }


        private string AuthorizedRole()
        {
            //  Find the authorized role for this method
            string strAuthorizedRole = "";

            IWEBMethodInfo IWEBMethodInfo = new IWEBMethodInfo();
            IWEBMethodInfo = IWEBMethods.GetMethodInDatabase(_PortalID, _MethodName);

            if (!(IWEBMethodInfo.SecuritySetting == ""))
            {
                strAuthorizedRole = IWEBMethodInfo.SecuritySetting;
            }
            else
            {
                strAuthorizedRole = "Host";
            }

            return strAuthorizedRole;
        }


        private string EncryptionKey()
        {
            string strEncryptionKey = "";

            strEncryptionKey = IWebController.GetIWebSettings(_PortalID, "SecurityKey");
            return strEncryptionKey;

        }


        private bool IsAuthorized(UserInfo UserInfo, string strAuthorizedRole)
        {
            DotNetNuke.Security.Roles.RoleController RoleController = new DotNetNuke.Security.Roles.RoleController();
            string[] strRoles = RoleController.GetRolesByUser(UserInfo.UserID, UserInfo.PortalID);

            if (UserInfo.IsSuperUser)
            {
                return true;
            }

            foreach (string objstrRole in strRoles)
            {
                if (objstrRole == strAuthorizedRole)
                {
                    return true;
                }
            }

            return false;

        }


        private string GetPassword(string parmPassword)
        {
            string strPassword = "";
            if (((_Encrypted) | (_WebPageCall)))
            {
                strPassword = HttpUtility.UrlDecode(parmPassword);
            }
            else
            {
                strPassword = parmPassword;
            }
            return strPassword;
        }

    }

}


